package com.gis.dto;

import com.gis.enums.QualityReportEnum;
import lombok.Data;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

@Data
public class WaterQualityReportDTO {
    private Integer stationId;
    private String tideStatus;
    private String name;
    private Float latitude;
    private Float longitude;
    private Float ph;
    private Float dissolvedOxygen;
    private Float cod;
    private Float n;
    private Float po4;
    private Float petroleumClass;
    private Float copper;
    private Float zinc;
    private Float lead;
    private Float cadmium;
    private Float mercury;
    private Float arsenic;
    private Float chromium;
    private Float sulfide;
    private Float voc;

    // 各指标分类
    private int classPh;
    private int classDissolvedOxygen;
    private int classCod;
    private int classN;
    private int classPo4;
    private int classPetroleumClass;
    private int classCopper;
    private int classZinc;
    private int classLead;
    private int classCadmium;
    private int classMercury;
    private int classArsenic;
    private int classChromium;
    private int classSulfide;
    private int classVoc;


    /**
     * 指标分类
     */
    public void setClassPh() {
        this.classPh = classifyPh(this.ph).getCode();
    }

    public void setClassDissolvedOxygen() {
        this.classDissolvedOxygen = classifyDissolvedOxygen(this.dissolvedOxygen).getCode();
    }

    public void setClassCod() {
        this.classCod = classifyChemicalOxygenDemand(this.cod).getCode();
    }

    public void setClassN() {
        this.classN = classifyInorganicNitrogen(this.n).getCode();
    }

    public void setClassPo4() {
        this.classPo4 = classifyActivePhosphate(this.po4).getCode();
    }

    public void setClassPetroleumClass() {
        this.classPetroleumClass = classifyPetroleum(this.petroleumClass).getCode();
    }

    public void setClassCopper() {
        this.classCopper = classifyCopper(this.copper).getCode();
    }

    public void setClassZinc() {
        this.classZinc = classifyZinc(this.zinc).getCode();
    }

    public void setClassLead() {
        this.classLead = classifyLead(this.lead).getCode();
    }

    public void setClassCadmium() {
        this.classCadmium = classifyCadmium(this.cadmium).getCode();
    }

    public void setClassMercury() {
        this.classMercury = classifyMercury(this.mercury).getCode();
    }

    public void setClassArsenic() {
        this.classArsenic = classifyArsenic(this.arsenic).getCode();
    }

    public void setClassChromium() {
        this.classChromium = classifyTotalChromium(this.chromium).getCode();
    }

    public void setClassSulfide() {
        this.classSulfide = classifySulfide(this.sulfide).getCode();
    }

    public void setClassVoc() {
        this.classVoc = classifyVolatilePhenol(this.voc).getCode();
    }
    /**
     * 水质指标分类函数
     * @param ph
     * @return
     */
    private QualityReportEnum classifyPh(Float ph) {
        if (ph < 0) return QualityReportEnum.FIRST_CLASS;
        if (ph >= 7.8 && ph <= 8.5) return QualityReportEnum.FIRST_CLASS;
        if (ph >= 6.8 && ph <= 8.8) return QualityReportEnum.THIRD_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyDissolvedOxygen(Float dissolvedOxygen) {
        if (dissolvedOxygen < 0) return QualityReportEnum.FIRST_CLASS;
        if (dissolvedOxygen >= 6) return QualityReportEnum.FIRST_CLASS;
        if (dissolvedOxygen >= 5) return QualityReportEnum.SECOND_CLASS;
        if (dissolvedOxygen >= 4) return QualityReportEnum.THIRD_CLASS;
        if (dissolvedOxygen >= 3) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyChemicalOxygenDemand(Float cod) {
        if (cod < 0) return QualityReportEnum.FIRST_CLASS;
        if (cod <= 2) return QualityReportEnum.FIRST_CLASS;
        if (cod <= 3) return QualityReportEnum.SECOND_CLASS;
        if (cod <= 4) return QualityReportEnum.THIRD_CLASS;
        if (cod <= 5) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyInorganicNitrogen(Float inorganicNitrogen) {
        if (inorganicNitrogen < 0) return QualityReportEnum.FIRST_CLASS;
        if (inorganicNitrogen <= 0.20) return QualityReportEnum.FIRST_CLASS;
        if (inorganicNitrogen <= 0.30) return QualityReportEnum.SECOND_CLASS;
        if (inorganicNitrogen <= 0.40) return QualityReportEnum.THIRD_CLASS;
        if (inorganicNitrogen <= 0.50) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyActivePhosphate(Float activePhosphate) {
        if (activePhosphate < 0) return QualityReportEnum.FIRST_CLASS;
        if (activePhosphate <= 0.015) return QualityReportEnum.FIRST_CLASS;
        if (activePhosphate <= 0.030) return QualityReportEnum.SECOND_CLASS;
        if (activePhosphate <= 0.045) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyPetroleum(Float petroleum) {
        if (petroleum < 0) return QualityReportEnum.FIRST_CLASS;
        if (petroleum <= 0.05) return QualityReportEnum.FIRST_CLASS;
        if (petroleum <= 0.30) return QualityReportEnum.THIRD_CLASS;
        if (petroleum <= 0.50) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyCopper(Float copper) {
        if (copper < 0) return QualityReportEnum.FIRST_CLASS;
        if (copper <= 0.005) return QualityReportEnum.FIRST_CLASS;
        if (copper <= 0.010) return QualityReportEnum.SECOND_CLASS;
        if (copper <= 0.050) return QualityReportEnum.THIRD_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyLead(Float lead) {
        if (lead < 0) return QualityReportEnum.FIRST_CLASS;
        if (lead <= 0.001) return QualityReportEnum.FIRST_CLASS;
        if (lead <= 0.005) return QualityReportEnum.SECOND_CLASS;
        if (lead <= 0.010) return QualityReportEnum.THIRD_CLASS;
        if (lead <= 0.050) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyZinc(Float zinc) {
        if (zinc < 0) return QualityReportEnum.FIRST_CLASS;
        if (zinc <= 0.020) return QualityReportEnum.FIRST_CLASS;
        if (zinc <= 0.050) return QualityReportEnum.SECOND_CLASS;
        if (zinc <= 0.10) return QualityReportEnum.THIRD_CLASS;
        if (zinc <= 0.50) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyCadmium(Float cadmium) {
        if (cadmium < 0) return QualityReportEnum.FIRST_CLASS;
        if (cadmium <= 0.001) return QualityReportEnum.FIRST_CLASS;
        if (cadmium <= 0.005) return QualityReportEnum.SECOND_CLASS;
        if (cadmium <= 0.010) return QualityReportEnum.THIRD_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyMercury(Float mercury) {
        if (mercury < 0) return QualityReportEnum.FIRST_CLASS;
        if (mercury <= 0.00005) return QualityReportEnum.FIRST_CLASS;
        if (mercury <= 0.0002) return QualityReportEnum.SECOND_CLASS;
        if (mercury <= 0.0005) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyArsenic(Float arsenic) {
        if (arsenic < 0) return QualityReportEnum.FIRST_CLASS;
        if (arsenic <= 0.020) return QualityReportEnum.FIRST_CLASS;
        if (arsenic <= 0.030) return QualityReportEnum.SECOND_CLASS;
        if (arsenic <= 0.050) return QualityReportEnum.THIRD_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyTotalChromium(Float totalChromium) {
        if (totalChromium < 0) return QualityReportEnum.FIRST_CLASS;
        if (totalChromium <= 0.05) return QualityReportEnum.FIRST_CLASS;
        if (totalChromium <= 0.10) return QualityReportEnum.SECOND_CLASS;
        if (totalChromium <= 0.20) return QualityReportEnum.THIRD_CLASS;
        if (totalChromium <= 0.50) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifySulfide(Float sulfide) {
        if (sulfide < 0) return QualityReportEnum.FIRST_CLASS;
        if (sulfide <= 0.02) return QualityReportEnum.FIRST_CLASS;
        if (sulfide <= 0.05) return QualityReportEnum.SECOND_CLASS;
        if (sulfide <= 0.10) return QualityReportEnum.THIRD_CLASS;
        if (sulfide <= 0.20) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private QualityReportEnum classifyVolatilePhenol(Float volatilePhenol) {
        if (volatilePhenol < 0) return QualityReportEnum.FIRST_CLASS;
        if (volatilePhenol <= 0.005) return QualityReportEnum.FIRST_CLASS;
        if (volatilePhenol <= 0.010) return QualityReportEnum.THIRD_CLASS;
        if (volatilePhenol <= 0.050) return QualityReportEnum.FOURTH_CLASS;
        return QualityReportEnum.FIFTH_CLASS;
    }

    private Map<Integer, Integer> countIntFieldValues() throws IllegalAccessException {
        Map<Integer, Integer> valueCountMap = new HashMap<>();
        // 获取当前对象的所有字段
        Field[] fields = this.getClass().getDeclaredFields();
        for (Field field : fields) {
            // 设置字段可访问
            field.setAccessible(true);
            // 检查字段是否为 int 类型
            if (field.getType() == int.class) {
                int value = field.getInt(this);
                // 更新计数
                valueCountMap.put(value, valueCountMap.getOrDefault(value, 0) + 1);
            }
        }

        return valueCountMap;
    }
    private Map<Integer, Double> calculateValuePercentages() throws IllegalAccessException {
        Map<Integer, Integer> valueCountMap = countIntFieldValues();
        int totalCount = valueCountMap.values().stream().mapToInt(Integer::intValue).sum();
        Map<Integer, Double> percentageMap = new HashMap<>();

        for (Map.Entry<Integer, Integer> entry : valueCountMap.entrySet()) {
            double percentage = ((double) entry.getValue() / totalCount) * 100;
            percentageMap.put(entry.getKey(), percentage);
        }

        return percentageMap;
    }
    public int getComprehensiveClass() {
//        try {
//            Map<Integer, Double> percentages = calculateValuePercentages();
//            for (Map.Entry<Integer, Double> entry : percentages.entrySet()) {
//                System.out.printf("Value: %d, Percentage: %.2f%%\n", entry.getKey(), entry.getValue());
//                if(entry.getKey()==-1){
//                    continue;
//                }
//                if(entry.getKey()==1&&entry.getValue()>=80){
//                    return entry.getKey();
//                }
//                if(entry.getKey()==2&&entry.getValue()>=8){
//                    return entry.getKey();
//                }
//                if(entry.getKey()==3&&entry.getValue()>=5){
//                    return entry.getKey();
//                }
//                if(entry.getKey()==4&&entry.getValue()>=3){
//                    return entry.getKey();
//                }
//            }
//        } catch (IllegalAccessException e) {
//            e.printStackTrace();
//        }
//        return 5;

        int max = Integer.MIN_VALUE;

        max = Math.max(max, classPh);
        max = Math.max(max, classDissolvedOxygen);
        max = Math.max(max, classCod);
        max = Math.max(max, classN);
        max = Math.max(max, classPo4);
        max = Math.max(max, classPetroleumClass);
        max = Math.max(max, classCopper);
        max = Math.max(max, classZinc);
        max = Math.max(max, classLead);
        max = Math.max(max, classCadmium);
        max = Math.max(max, classMercury);
        max = Math.max(max, classArsenic);
        max = Math.max(max, classChromium);
        max = Math.max(max, classSulfide);
        max = Math.max(max, classVoc);
        return max;
    }


    public void print() {
        System.out.println("Station ID: " + stationId);
        System.out.println("TideStatus: " + tideStatus);
        System.out.println("Name: " + name);
        System.out.println("Latitude: " + latitude);
        System.out.println("Longitude: " + longitude);

        System.out.println("pH: " + ph + " - Class: " + classifyPh(ph));
        System.out.println("Dissolved Oxygen: " + dissolvedOxygen + " - Class: " + classifyDissolvedOxygen(dissolvedOxygen));
        System.out.println("COD: " + cod + " - Class: " + classifyChemicalOxygenDemand(cod));
        System.out.println("N: " + n + " - Class: " + classifyInorganicNitrogen(n));
        System.out.println("PO4: " + po4 + " - Class: " + classifyActivePhosphate(po4));
        System.out.println("Petroleum Class: " + petroleumClass + " - Class: " + classifyPetroleum(petroleumClass));
        System.out.println("Copper: " + copper + " - Class: " + classifyCopper(copper));
        System.out.println("Zinc: " + zinc + " - Class: " + classifyZinc(zinc));
        System.out.println("Lead: " + lead + " - Class: " + classifyLead(lead));
        System.out.println("Cadmium: " + cadmium + " - Class: " + classifyCadmium(cadmium));
        System.out.println("Mercury: " + mercury + " - Class: " + classifyMercury(mercury));
        System.out.println("Arsenic: " + arsenic + " - Class: " + classifyArsenic(arsenic));
        System.out.println("Chromium: " + chromium + " - Class: " + classifyTotalChromium(chromium));
        System.out.println("Sulfide: " + sulfide + " - Class: " + classifySulfide(sulfide));
        System.out.println("VOC: " + voc + " - Class: " + classifyVolatilePhenol(voc));

        System.out.println("Comprehensive Class: " + getComprehensiveClass());
    }
}
